package com.sinooceangroup.capital.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * 自定义 GatewayFilterFactory。
 *
 * @author: Leo.Wang, adwyxx@qq.com
 * @date: 2020/7/23 9:40
 */
@Component
public class CommonGatewayFilterFactory extends AbstractGatewayFilterFactory<CommonGatewayFilterFactory.Config> {

    /***
     * 一定要有无参构造函数
     */
    public CommonGatewayFilterFactory() {
        //注意：没有该句将会引起无法java.lang.Object cannot be cast AuthorizeGatewayFilterFactory$Config异常
        super(Config.class);
        //logger.info("Loaded GatewayFilterFactory [Authorize]");
    }

    /***
     * 重写apply方法，实现Filter业务逻辑
     * @param config : 配置信息
     * @return: FilterChain
     */
    @Override
    public GatewayFilter apply(CommonGatewayFilterFactory.Config config) {
        return ((exchange, chain) -> {
            //1. Pre操作
            if (config.isUse()){
                ServerHttpRequest request = exchange.getRequest();
            }
            else {

            }
            //2. Post操作，Controller方法调用之后对返回的Response做处理
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                ServerHttpResponse response = exchange.getResponse();


            }));
        });
    }

    /***
     * 内部静态类，自定义Filter业务处理是需要用的的一些配置属性可以在该类中定义
     * 在application.properties / yaml / yml 配置文件中使用到该Filter时可以指定Config定义的属性值
     */
    public static class Config{
        private boolean isUse;
        private String type;

        public boolean isUse() {
            return isUse;
        }

        public void setUse(boolean use) {
            isUse = use;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public Config(boolean isUse, String type) {
            this.isUse = isUse;
            this.type = type;
        }
    }
}
